Immutable Data Structures জাভাতে এমন ডেটা স্ট্রাকচার যা একবার তৈরি হলে পরিবর্তন করা যায় না। Immutable ক্লাস Serialize এবং Deserialize করতে হলে কিছু কনফিগারেশন প্রয়োজন হয় কারণ Immutable ক্লাসে সাধারণত setter মেথড থাকে না।
Jackson লাইব্রেরি Immutable ক্লাস হ্যান্ডল করার জন্য সহজ এবং কার্যকর পদ্ধতি প্রদান করে। নিচে বিস্তারিত আলোচনা করা হলো:
1. Immutable Class Serialization
Immutable ক্লাস Serialize করা সহজ কারণ এটি কেবলমাত্র ডেটা পড়ার প্রপার্টি (getter) প্রয়োজন।
উদাহরণ: Immutable Class Serialization
import com.fasterxml.jackson.databind.ObjectMapper;
class Person {
private final String name;
private final int age;
// Constructor
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getters only (No setters)
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class ImmutableSerializationExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
// Immutable Object তৈরি
Person person = new Person("John Doe", 30);
// Serialize
String json = mapper.writeValueAsString(person);
System.out.println("Serialized JSON: " + json);
}
}
আউটপুট:
{
"name": "John Doe",
"age": 30
}
2. Immutable Class Deserialization
Deserialize করার সময় সমস্যার কারণ হতে পারে:
- Immutable ক্লাসের কোনো
setterথাকে না। - ফিল্ডগুলো
finalহওয়ায় সরাসরি পরিবর্তন সম্ভব নয়।
Jackson এর দুটি পদ্ধতি দিয়ে Immutable ক্লাস Deserialize করা যায়:
- Constructor-based Deserialization
- Builder Pattern
2.1 Constructor-based Deserialization
Jackson @JsonCreator এবং @JsonProperty অ্যানোটেশন ব্যবহার করে Constructor-based Deserialization সমর্থন করে।
উদাহরণ: Constructor-based Deserialization
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
class Employee {
private final String name;
private final int id;
// Constructor with @JsonCreator and @JsonProperty
@JsonCreator
public Employee(@JsonProperty("name") String name, @JsonProperty("id") int id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public int getId() {
return id;
}
@Override
public String toString() {
return "Employee{name='" + name + "', id=" + id + '}';
}
}
public class ConstructorBasedDeserializationExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String json = "{\"name\":\"Alice\",\"id\":101}";
// Deserialize
Employee employee = mapper.readValue(json, Employee.class);
System.out.println("Deserialized Object: " + employee);
}
}
আউটপুট:
Deserialized Object: Employee{name='Alice', id=101}
2.2 Builder Pattern
Builder Pattern ব্যবহার করলে Immutable ক্লাসের জন্য আরও ফ্লেক্সিবিলিটি পাওয়া যায়। Jackson @JsonPOJOBuilder এবং @JsonDeserialize অ্যানোটেশন ব্যবহার করে Builder Pattern সমর্থন করে।
উদাহরণ: Builder Pattern
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;
@JsonDeserialize(builder = Product.Builder.class)
class Product {
private final String name;
private final double price;
private Product(Builder builder) {
this.name = builder.name;
this.price = builder.price;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
@Override
public String toString() {
return "Product{name='" + name + "', price=" + price + '}';
}
@JsonPOJOBuilder(withPrefix = "")
public static class Builder {
private String name;
private double price;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder price(double price) {
this.price = price;
return this;
}
public Product build() {
return new Product(this);
}
}
}
public class BuilderPatternExample {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
String json = "{\"name\":\"Laptop\",\"price\":75000.0}";
// Deserialize
Product product = mapper.readValue(json, Product.class);
System.out.println("Deserialized Object: " + product);
}
}
আউটপুট:
Deserialized Object: Product{name='Laptop', price=75000.0}
3. টিপস এবং সুপারিশ
(a) Preferred Approach
- যদি Immutable ক্লাস ছোট এবং সরল হয়, Constructor-based Deserialization আদর্শ।
- বড় বা জটিল Immutable ক্লাসের ক্ষেত্রে Builder Pattern বেশি কার্যকর।
(b) Final Fields
- Immutable ক্লাসের ফিল্ডগুলো
finalরাখা ভালো, এবং Jackson এগুলো সঠিকভাবে সমর্থন করে।
(c) JSON Validation
@JsonPropertyব্যবহার করে প্রপার্টি বাধ্যতামূলক (required) করা যায়:
@JsonProperty(value = "name", required = true)
private final String name;
(d) Global Configuration
Jackson এর ObjectMapper-এ Immutable টাইপ সঠিকভাবে হ্যান্ডল করার জন্য কনফিগারেশন যোগ করা যায়:
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
4. Use Cases
- Immutable Domain Models: যেমন, DTOs বা Value Objects।
- Configuration Loading: Immutable কনফিগারেশন ক্লাস JSON থেকে লোড করা।
- REST API Responses: Immutable ক্লাসের মাধ্যমে API রেসপন্স মডেল তৈরি।
Jackson Immutable ক্লাস Serialize এবং Deserialize করার জন্য শক্তিশালী সমাধান প্রদান করে। ছোট ক্লাসের জন্য Constructor-based পদ্ধতি এবং জটিল ক্লাসের জন্য Builder Pattern ব্যবহার করা বেস্ট প্র্যাকটিস।
Read more